package cn.song.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * AES加密工具  模式：CBC  补码方式：PKCS7Padding
 * @author Administrator
 *133E80BFC69ACEE0826DEFB46D0F267A8EF3D5C1F8712210B87B4157175F3175
 *133E80BFC69ACEE0826DEFB46D0F267A8EF3D5C1F8712210B87B4157175F3175
 */
@Slf4j
public class AESMysql {
	 public static final String KEY = "yqhfenxiao";
	    public static void main(String... args) throws Exception {


	        String result = encrpt("15039072103");
	        System.out.println("加密结果：" + result.length()); //加密
	        System.out.println("解密结果：" + decrpt(result)); //解密加密的数据
	    }

	    /**
	     * AES解密
	     *
	     * @param data 待解密字符串
	     * @return 解密结果
	     * @throws Exception 抛出本方法的执行异常
	     */
	    public static String decrpt(String data)  {
	        try {
				final Cipher decryptCipher = Cipher.getInstance("AES");
				decryptCipher.init(Cipher.DECRYPT_MODE, generateMySQLAESKey(KEY, StandardCharsets.UTF_8));
				return new String(decryptCipher.doFinal(Hex.decodeHex(data.toCharArray())),
						StandardCharsets.UTF_8);
	        }catch (Exception e){
				log.error("AES解密报错：", e);
			}
			 return null;
	    }

	    /**
	     * AES加密
	     *
	     * @param data 待加密字符串
	     * @return 加密结果
	     * @throws Exception 抛出本方法的执行异常
	     */
	    public static String encrpt(String data)  {
	        try {
				final Cipher encryptCipher = Cipher.getInstance("AES");
				encryptCipher.init(Cipher.ENCRYPT_MODE, generateMySQLAESKey(KEY, StandardCharsets.UTF_8));
				char[] code = Hex.encodeHex(encryptCipher.doFinal(data.getBytes( StandardCharsets.UTF_8)));
				StringBuilder builder = new StringBuilder();
				for (char d : code) {
				    builder.append(d);
				}
				return builder.toString().toUpperCase();
			} catch (Exception e) {
				log.error("AES加密错误", e);
			}
			return null;

	    }

	    /**
	     * 生成AES加解密用的SecretKeySpec
	     *
	     * @param key     加解密用的秘钥
	     * @param charset 编码设置 默认UTF-8
	     * @return SecretKeySpec实例
	     */
	    public static SecretKeySpec generateMySQLAESKey(String key, Charset charset) {
	        try {
	            final byte[] finalKey = new byte[16];
	            int i = 0;
	            for (byte b : key.getBytes(charset)) {
	                finalKey[i++ % 16] ^= b;
	            }

	            //System.out.println(new String(finalKey));
	            return new SecretKeySpec(finalKey, "AES");
	        } catch (Exception e) {
	            log.error("执行异常，异常信息：", e);
	            return null;
	        }
	    }

}
